/*
 * Copyright 2012 Marsrutai.lt
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package lt.marsrutai.mobile.android.activity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lt.marsrutai.mobile.android.AppContext;
import lt.marsrutai.mobile.android.R;
import lt.marsrutai.mobile.android.activity.intent.DataDownloadProgressIntentHolder;
import lt.marsrutai.mobile.android.activity.intent.ScopesIntentHolder;
import lt.marsrutai.mobile.android.activity.intent.StopSearchIntentHolder;
import lt.marsrutai.mobile.android.activity.intent.TaskIntentHolder;
import lt.marsrutai.mobile.android.bundle.ScopeDownloadBundleHolder;
import lt.marsrutai.mobile.android.fragment.ScopeDownloadFragment;
import lt.marsrutai.mobile.android.fragment.task.GetAvailableScopesTaskDialogFragment;
import lt.marsrutai.mobile.android.fragment.task.TaskDialogFragment;
import lt.marsrutai.mobile.android.manager.ActivityManager;
import lt.marsrutai.mobile.android.model.MobileScope;
import lt.marsrutai.mobile.android.service.impl.DataDownloadService;
import lt.marsrutai.mobile.android.task.GetAvailableScopesTask;
import lt.marsrutai.mobile.android.util.PreferenceUtils;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.LocalBroadcastManager;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ProgressBar;

import com.actionbarsherlock.app.ActionBar;
import com.google.analytics.tracking.android.EasyTracker;

public class ScopesActivity extends BaseActivity {

    private static final String GET_SCOPES_TASK_FRAGMENT_TAG = "getScopesTaskFragment";

    private FragmentManager fragmentManager;
    private ActivityManager manager;

    private List<MobileScope> scopes;
    private Map<String, ScopeDownloadFragment> scopeDownloadFragments;

    private BroadcastReceiver downloadProgressReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            updateDownloadProgress(intent);
        }
    };

    private BroadcastReceiver scopeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            TaskIntentHolder holder = new TaskIntentHolder(intent);
            scopes = holder.getListResult();

            if (holder.getStatus() == GetAvailableScopesTask.RESULT_NOT_RESOLVED) {
                manager.runOnUiThread(manager.errorRes);
            }
            updateActionBar(false);
        }
    };

    private void updateDownloadProgress(Intent intent) {

        DataDownloadProgressIntentHolder intentHolder = new DataDownloadProgressIntentHolder(intent);
        MobileScope mobileScope = getCurrentMobileScope();
        if (mobileScope == null) {
            return;
        }        
        if (!mobileScope.getFolder().equals(intentHolder.getScopeFolder())) {
            return;
        }

        CheckBox downloadDataCheckbox = (CheckBox) findViewById(R.id.download_data);
        ProgressBar progressBar = (ProgressBar) findViewById(R.id.download_progress);

        if (null == downloadDataCheckbox || null == progressBar) {
            return;
        }

        if (intentHolder.getProgress() < 0) {
            // Download failed.
            downloadDataCheckbox.setEnabled(true);
            downloadDataCheckbox.setChecked(false);
            progressBar.setVisibility(View.INVISIBLE);
        }
        else if (intentHolder.getProgress() >= intentHolder.getMax()) {
            // Download finished.
            downloadDataCheckbox.setEnabled(true);
            progressBar.setVisibility(View.INVISIBLE);
        }
        else {
            // Download in progress.
            downloadDataCheckbox.setEnabled(false);
            downloadDataCheckbox.setChecked(true);
            progressBar.setVisibility(View.VISIBLE);
            progressBar.setProgress(intentHolder.getProgress());
            progressBar.setMax(intentHolder.getMax());
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        fragmentManager = getSupportFragmentManager();
        manager = new ActivityManager(this, R.string.no_data_scope_message);

        AppContext.getCacheUpdateManager().checkForCacheUpdates(this, false);

        restoreState(savedInstanceState);
    }

    @Override
    public void onResume() {
        super.onResume();
        registerReceiver(downloadProgressReceiver, new IntentFilter(DataDownloadService.BROADCAST_ACTION));
        LocalBroadcastManager.getInstance(this).registerReceiver(scopeReceiver, new IntentFilter(GetAvailableScopesTask.BROADCAST_ACTION));

        TaskDialogFragment<?, ?, ?> taskFragment = (TaskDialogFragment<?, ?, ?>) fragmentManager.findFragmentByTag(GET_SCOPES_TASK_FRAGMENT_TAG);

        // Start downloading only if we don't have any scopes, and task fragments has not been retained
        if (!TaskDialogFragment.isActive(taskFragment) && scopes == null) {
            TaskDialogFragment.download(fragmentManager, 
                    GetAvailableScopesTaskDialogFragment.class, GET_SCOPES_TASK_FRAGMENT_TAG);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(downloadProgressReceiver);

        // Unregister since the activity is about to be closed.
        LocalBroadcastManager.getInstance(this).unregisterReceiver(scopeReceiver);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        ScopesIntentHolder intentHolder = new ScopesIntentHolder(new Bundle());
        intentHolder.setScopeList(scopes);

        outState.putAll(intentHolder.getIntent().getExtras());

        super.onSaveInstanceState(outState);
    }

    private void restoreState(Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            ScopesIntentHolder intentHolder = new ScopesIntentHolder(savedInstanceState);

            scopes = intentHolder.getScopeList();
            updateActionBar(true);
        }
    }

    @Override
    protected void setupActionBar(final ActionBar actionBar) {
        super.setupActionBar(actionBar);
        actionBar.setDisplayHomeAsUpEnabled(false);
        actionBar.setDisplayShowTitleEnabled(true);
    }

    @Override
    protected int getNavigationMode() {
        return ActionBar.NAVIGATION_MODE_LIST;
    }

    public void updateActionBar(Boolean isRestoreState) {
        // reinitialize the action bar - fill up downloaded scopes
        setupActionBar(getSupportActionBar());

        selectPreferedScope(isRestoreState);
    }

    @Override
    public NavMenuData getNavMenuData() {
        if (scopes == null) {
            return super.getNavMenuData();
        }

        scopeDownloadFragments = new HashMap<String, ScopeDownloadFragment>();

        List<String> scopeNames = new ArrayList<String>(scopes.size());
        for (MobileScope mobileScope : scopes) {
            scopeNames.add(mobileScope.getName());

            ScopeDownloadBundleHolder holder = new ScopeDownloadBundleHolder();
            holder.setScopeFolder(mobileScope.getFolder());
            holder.setScopeName(mobileScope.getName());
            holder.setStoredVersion(mobileScope.getStoredVersion());

            ScopeDownloadFragment scopeDownloadFragment = new ScopeDownloadFragment();
            scopeDownloadFragment.setArguments(holder.getBundle());
            scopeDownloadFragments.put(mobileScope.getFolder(), scopeDownloadFragment);
        }

        return new NavMenuData(scopeNames.toArray(new String[] {}));
    }

    @Override
    public boolean onNavigationItemSelected(int itemPosition, long itemId) {
        String currentScopeFolder = scopes.get(itemPosition).getFolder();

        String previousScopeFolder = PreferenceUtils.getPreferenceValue(this, PreferenceUtils.SELECTED_SCOPE_FOLDER);
        PreferenceUtils.setStringPreferenceValue(this, PreferenceUtils.SELECTED_SCOPE_FOLDER, currentScopeFolder);

        Fragment currentScopeDownloadFragment = scopeDownloadFragments.get(currentScopeFolder);

        getSupportFragmentManager().beginTransaction().replace(R.id.scope_download_fragment_frame, currentScopeDownloadFragment).commit();

        if (!previousScopeFolder.equals(currentScopeFolder)) {            
            EasyTracker.getTracker().trackEvent("scopes", "selectScope", String.format("%s > %s", previousScopeFolder, currentScopeFolder), 0L);
        }
        return true;
    }

    @Override
    public void setupView() {
        setContentView(R.layout.scopes_layout);
    }

    private void selectPreferedScope(Boolean isRestoreState) {
        if (null == scopes) {
            return;
        }

        String selectedScopeFolder = PreferenceUtils.getPreferenceValue(this, PreferenceUtils.SELECTED_SCOPE_FOLDER);
        for (int i = 0; i < scopes.size(); i++) {
            if (selectedScopeFolder.equals(scopes.get(i).getFolder())) {
                getSupportActionBar().setSelectedNavigationItem(i);
            }
        }
        
        if (!isRestoreState) {
            EasyTracker.getTracker().trackEvent("scopes", "savedScope", selectedScopeFolder, 0L);
        }
    }

    @Override
    public boolean onSearchRequested() {
        MobileScope mobileScope = getCurrentMobileScope();
        if (mobileScope == null) {
            return false;
        }

        StopSearchIntentHolder stopSearchIntentHolder = new StopSearchIntentHolder(new Bundle());
        stopSearchIntentHolder.setScopeFolder(mobileScope.getFolder());
        stopSearchIntentHolder.setScopeName(mobileScope.getName());

        startSearch(null, false, stopSearchIntentHolder.getIntent().getExtras(), false);

        return true;
    };

    public MobileScope getCurrentMobileScope() {
        if (scopes == null) {
            return null;
        }
        return scopes.get(getSupportActionBar().getSelectedNavigationIndex());
    }

}
